﻿#ifndef _ARP_H_
#define _ARP_H_

#include "nlist.h"
#include "net_err.h"
#include "debug.h"
#include "netif.h"

#define ARP_HW_ETHER 1 // arp中硬件类型
#define ARP_REQUEST 1  // arp 响应标识
#define ARP_REPLY 2    // arp请求标识

// arp 表项结构
typedef struct _arp_entry_t
{
    uint8_t ipaddr[IPV4_ADDR_SIZE];
    uint8_t hwaddr[ETHER_HWA_SIZE];
    nlist_node_t node;
    nlist_t buf_list; // 用于缓存因为查表等待而未处理的包
    netif_t *netif;
    enum
    {
        NET_ARP_FREE,
        NET_ARP_WAITING,
        NET_ARP_RESOLVED
    } state;

    int tmo;   // 剩余可被扫描次数(本来想做成时间的...)
    int retry; // arp剩余重新询问次数
} arp_entry_t;

#pragma pack(1)
// arp数据包结构
typedef struct _arp_pkt_t
{
    uint16_t htype;  // 硬件类型
    uint16_t ptype;  // 协议类型
    uint8_t hwlen;   // 硬件地址大小
    uint8_t plen;    // 协议地址长度
    uint16_t opcode; // 操作标识
    uint8_t sender_hwaddr[ETHER_HWA_SIZE];
    uint8_t sender_ipaddr[IPV4_ADDR_SIZE];
    uint8_t target_hwaddr[ETHER_HWA_SIZE];
    uint8_t target_ipaddr[IPV4_ADDR_SIZE];
} arp_pkt_t;
#pragma pack()

net_err_t arp_init();
net_err_t arp_make_request(netif_t *netif, const ipaddr_t *ipaddr);
net_err_t arp_make_reply(netif_t *netif, pktbuf_t *buf);
net_err_t arp_make_gratuitous(netif_t *netif);
net_err_t arp_in(netif_t *netif, pktbuf_t *buf);
arp_entry_t *arp_find(uint8_t *ip);
net_err_t arp_resolve(netif_t *netif, ipaddr_t *dest, pktbuf_t *buf);
void arp_clear(netif_t *netif);
net_err_t arp_update_from_ipbuf(netif_t *netif, pktbuf_t *buf);

#endif